<template>
  <vxe-modal
    v-model="computedValue"
    v-bind="computedProps"
    @close="handleCloseModal"
    @zoom="handleZoom"
  >
    <template #default>
      <div class="erp-form-modal-body">
        <div
          v-if="multiple"
          class="erp-form-modal-selected"
        >
          <div class="selected-box">
            <div class="selected-title">
              已选择项
              <span
                class="clear-all-selected"
                @click="clearAllSelection"
              >
                清空
              </span>
            </div>
            <div class="selected-body">
              <div v-if="selectedList && selectedList.length > 0">
                <div
                  v-for="(item,index) in selectedList"
                  :key="index"
                  class="selected-item"
                  @click="handleClearItem(item, index)"
                >
                  <span>{{ item[modelNameField] }}</span>
                  <i class="el-icon-close" />
                </div>
              </div>
              <div v-else>
                暂未选择选项
              </div>
            </div>
          </div>
        </div>
        <div
          class="erp-form-modal-list"
          :class="{single:!multiple}"
        >
          <div style="background-color: #fff;height: 100%">
            <erp-list-page
              v-if="options"
              ref="erpListPage"
              :options.sync="computedOptions"
              :multiple-selected-ids="multiple ? multipleSelectedIds: []"
              @single-select-close="handleSingleSelectClose"
              @multiple-select-change="handleMultipleSelectChange"
              @multiple-select-all-change="handleMultipleSelectAllChange"
              @list-change="handleDataChange"
              @change-options="handleChangeOptions"
            />
          </div>
        </div>
      </div>
    </template>

    <template slot="footer">
      <slot name="footer-append" />
      <el-button
        v-if="multiple"
        type="primary"
        :loading="saveLoading"
        @click="handleSaveModal"
      >
        {{ $t('common.confirm') }}
      </el-button>
      <el-button @click="handleCloseModal">
        {{ $t('common.close') }}
      </el-button>
    </template>
  </vxe-modal>
</template>

<script>
const ErpListPage = () => import("@/components/erp/ErpListPage/ErpListPage");
import {cloneJson, toast} from "../../../utils";
import {base as request} from '@/request';
/**
 * 表格中的某行需要分配多个值时使用，例如：一个业务员要分配多个客户
 */
export default {
  name: "ErpListAssign",
  components: {
    ErpListPage
  },
  props: {
    /**
     * 默认值，一般为id列表
     * @public
     */
    idList: {
      type: [String, Array, Object, Number],
      default: null
    },
    /**
     * 模态框的配置项
     * ```json
     {
        title: '分配员工',
        showFooter: true,
        resize: true,
        transfer: true,
        zIndex: 1300,
        width: '98%',
        height: '98%',
     }
     ```
     * @public
     */
    props: {
      type: Object,
      default: () => {}
    },
    /**
     * 额外配置参数，例如：需要获取的值在列表中叫userId，需要显示的值在列表中叫userName
     * {
          modalIdField: "userId",
          modalNameField: "userName"
        }
     * @public
     */
    extra: {
      type: Object,
      default () {
        return {
          modalIdField: null,
          modalNameField: null
        };
      }
    },
    /**
     * 请求api设置
     * @public
     */
    request: {
      type: Object,
      default () {
        return {
          url: "",
          formFunction: "",
          form: {
            "id":"$q_id"
          }
        };
      }
    },
    /**
     * 默认值api设置
     * @public
     */
    defaultValue: {
      type: Object,
      default () {
        return {
          url: "",
          formFunction: "",
          form: {
            "id":"$q_id"
          }
        };
      }
    },
    /**
     * 是否显示当前表单
     * @public
     */
    value: {
      type: Boolean,
      default: false
    },
    /**
     * 是否开启多选
     * @public
     */
    multiple: {
      type: Boolean,
      default: true
    },
    /**
     * 额外参数
     * @public
     */
    query: {
      type: Object,
      default: () => {}
    },
    /**
     * [配置示例](../eg/Button.html#listButton.assign)
     * @public
     */
    options: {
      type: Object,
      default: () => {}
    },
  },
  data () {
    return {
      saveLoading: false,
      tableList: [],
      checkedList: []
    };
  },
  computed: {
    computedValue: {
      get () {
        return this.value;
      },
      set (val) {
        this.$emit('value-change', val);
      }
    },
    computedProps () {
      let defaultConfig = {
        title: '分配员工',
        showFooter: true,
        resize: true,
        transfer: true,
        zIndex: 1300,
        width: '98%',
        height: '98%',
      };
      return Object.assign(defaultConfig, this.props ? this.props : {});
    },
    computedOptions:{
      get() {
        return this.options;
      },
      set (val) {
        this.$emit('update:options', val);
      }
    },
    multipleSelectedIds () {
      let selectedList = this.selectedList;
      let array = [];
      if (selectedList && selectedList.length > 0) {
        for (let i in selectedList) {
          array.push(selectedList[i][this.modelIdField]);
        }
      }
      return array;
    },
    modelIdField () {
      return this.extra && this.extra.modalIdField ?  this.extra.modalIdField : null;
    },
    modelNameField () {
      return this.extra && this.extra.modalNameField ?  this.extra.modalNameField : null;
    },
    selectedList: {
      set (val) {
        this.checkedList = val;
      },
      get () {
        let ids = this.defaultIdsValue;
        let checkedList = this.checkedList;
        let check = [];
        if (checkedList === null) {
          if (ids) {
            ids = ids.split(',');
            let names = this.value ? this.value.split(',') : [];
            if (ids && ids.length > 0) {
              for(let i in ids) {
                check.push({
                  [this.modelIdField]: ids[i],
                  [this.modelNameField]: names[i]
                });
              }
            }
          }
        } else {
          check = checkedList;
        }
        let data = this.tableList;
        let modelIdField = this.modelIdField;
        return check ? check.map((item) => {
          if (data && data.length > 0) {
            for (let i in data) {
              if (data[i][modelIdField] == item[modelIdField]) {
                return data[i];
              }
            }
          }
          return item;
        }) : [];
      }
    },
    requestFormFunction () {
      return this.request && this.request.formFunction ? this.request.formFunction : null;
    },
    defaultValueFormFunction () {
      return this.defaultValue && this.defaultValue.defaultValueFormFunction ? this.defaultValue.defaultValueFormFunction : null;
    },
    requestForm () {
      return this.request && this.request.form ? this.request.form : null;
    },
    defaultValueForm () {
      return this.defaultValue && this.defaultValue.form ? this.defaultValue.form : null;
    },
  },
  mounted() {
    this.getDefaultIds();
  },
  methods: {
    /**
     * 缩放表单大小
     * @private
     */
    handleZoom () {
      this.$nextTick(() => {
        this.$refs.erpListPage.fetchTableHeight();
      });
    },
    /**
     * 获取默认值
     * @private
     */
    getDefaultIds () {
      if (this.defaultValue && this.defaultValue.url) {
        let form = this.generateDefaultValueFormByQuery(this.query, this.idList);
        request.post(this.defaultValue.url, form)
          .then((res) => {
            this.checkedList = res.data;
          });
      }
    },
    /**
     * 监听修改配置项
     * @private
     * @param options
     */
    handleChangeOptions (options) {
      this.computedOptions = options;
    },
    /**
     * 监听关闭表单
     * @private
     */
    handleCloseModal () {
      this.computedValue = false;
    },
    /**
     * 监听更新列表
     * @private
     * @param data
     */
    handleDataChange (data) {
      this.tableList = data;
    },
    /**
     * 清除所有选项
     * @private
     */
    clearAllSelection () {
      this.checkedList = [];
      this.$refs.erpListPage.$refs.erpPageTable.$refs.table.$refs.erpTable.clearSelection();
    },
    /**
     * 清除某一项
     * @private
     * @param item
     * @param index
     */
    handleClearItem (item, index) {
      let selectedList = this.selectedList;
      selectedList.splice(index, 1);
      this.selectedList = selectedList;
      this.$refs.erpListPage.$refs.erpPageTable.$refs.table.$refs.erpTable.toggleCheckboxRow(item);
    },
    /**
     * 关闭单选
     * @private
     * @param data
     */
    handleSingleSelectClose (data) {
      let item = data.item;

      this.handleCloseModal();
    },
    /**
     * 监听多选值变化
     * @private
     * @param data
     */
    handleMultipleSelectChange (data) {
      let checked = false;
      if (data.selection && data.selection.length > 0) {
        for (let i in data.selection) {
          if (data.selection[i][this.modelIdField] == data.row[this.modelIdField]) {
            checked = true;
            break;
          }
        }
      }
      this.selectedIds = [data.row[this.modelIdField]];
      this.multipleSelectChange([data.row], checked);
    },
    /**
     * 监听多选全选
     * @private
     * @param data
     */
    handleMultipleSelectAllChange (data) {
      let checked = false;
      let list = cloneJson(this.tableList);
      if (data.selection && data.selection.length > 0) {
        checked = true;
        list = data.selection;
      }
      this.multipleSelectChange(list, checked);
    },
    /**
     * 监听多选值变化
     * @private
     * @param data
     * @param checked
     */
    multipleSelectChange (data, checked) {
      let idField = this.modelIdField;
      let checkedList = cloneJson(this.selectedList);
      if (idField && data && data.length > 0) {
        if (checked) {
          checkedList = checkedList.concat(data);
          let obj = {};
          checkedList = checkedList.reduce((cur, next) => {
            obj[next[idField]] ? "" : obj[next[idField]] = true && cur.push(next);
            return cur;
          }, []);
        } else {
          let newCheckedList = [];
          for (let i in checkedList) {
            let isDelete = false;
            for (let j in data) {
              if (checkedList[i][idField] === data[j][idField]) {
                isDelete = true;
                break;
              }
            }
            if (!isDelete) {
              newCheckedList.push(checkedList[i]);
            }
          }
          checkedList = newCheckedList;
        }
      }
      this.selectedList = checkedList;
    },
    /**
     * 更新表单
     * @private
     */
    handleSaveModal () {
      let checkedList = this.checkedList;
      let ids = [];
      let names = [];
      if (checkedList && checkedList.length > 0) {
        for (let i in checkedList) {
          if (this.modelIdField) {
            ids.push(checkedList[i][this.modelIdField]);
          }
          if (this.modelNameField) {
            names.push(checkedList[i][this.modelNameField]);
          }
        }
      }
      if (this.request && this.request.url) {
        let form = this.generateFormByQuery(this.query, ids, this.idList);
        request.post(this.request.url, form)
          .then(() => {
            toast({
              message: this.$t('common.saveSuccess'),
              type: 'success'
            });
            this.handleCloseModal();
          });
      }
    },
    /**
     * 生成表单
     * @private
     * @param query
     * @param selectedIds
     * @param Ids
     * @returns {{}|any}
     */
    generateFormByQuery (query, selectedIds, Ids) {
      if (this.requestFormFunction) {
        try{
          return new Function('query', 'selectedIds', 'ids', this.requestFormFunction )(query, selectedIds, Ids);
        }catch (e) {
          console.log('requestFormFunction error');
          console.log(e);
        }
      } else if (this.requestForm) {
        let formObj = cloneJson(this.requestForm);
        if (formObj) {
          for (let i in formObj) {
            if (typeof formObj[i] === 'string' && formObj[i].substr(0, 3) === '$q_' && formObj[i].length > 3) {
              let field = formObj[i].substr(3);
              formObj[i] = query[field];
            }else if (typeof formObj[i] === 'string' && formObj[i] === '$id') {
              formObj[i] = Ids;
            } else if (typeof formObj[i] === 'string' && formObj[i] === '$sid') {
              formObj[i] = selectedIds;
            }
          }
        }
        return formObj;
      }
      return {};
    },
    /**
     * 生成默认值
     * @private
     * @param query
     * @param id
     * @returns {{}|any}
     */
    generateDefaultValueFormByQuery (query, id) {
      if (this.defaultValueFormFunction) {
        try{
          return new Function('query','id', this.requestFormFunction )(query, id);
        }catch (e) {
          console.log('defaultValueFormFunction error');
          console.log(e);
        }
      } else if (this.defaultValueForm) {
        let formObj = cloneJson(this.defaultValueForm);
        if (formObj) {
          for (let i in formObj) {
            if (typeof formObj[i] === 'string' && formObj[i].substr(0, 3) === '$q_' && formObj[i].length > 3) {
              let field = formObj[i].substr(3);
              formObj[i] = query[field];
            }else if (typeof formObj[i] === 'string' && formObj[i] === '$id') {
              formObj[i] = id;
            }
          }
        }
        return formObj;
      }
      return {};
    }
  }
};
</script>

<style lang="scss" scoped>
    $primaryColor: var(--primary-color);
    .erp-form-modal-body{
        height: 100%;
        display: flex;
        flex-wrap: nowrap;
        justify-content: space-between;
        .erp-form-modal-selected{
            border: 1px solid #ccc;
            box-sizing: border-box;
            width: 250px;
            padding: 15px;
            .selected-box{
                border-radius: 2px;
                background-color: #fff;
                height: 100%;
                .selected-title{
                    padding: 0 15px;
                    border-bottom: 1px solid #eee;
                    height: 40px;
                    line-height: 40px;
                    font-size: 14px;
                    font-weight: bold;
                    .clear-all-selected{
                        cursor: pointer;
                        user-select: none;
                    }

                }
                .selected-body{
                    height: calc(100% - 40px);
                    padding: 15px;
                    overflow-y: auto;
                    .selected-item{
                        cursor: pointer;
                        padding: 0 10px;
                        float:left;
                        height: 26px;
                        line-height: 26px;
                        border-radius: 2px;
                        margin-right: 10px;
                        margin-bottom: 10px;
                        background-color: #eee;
                        color: #000;
                        box-sizing: border-box;
                        border: 1px solid #eee;
                        user-select: none;
                        &:hover{
                            border: 1px solid $primaryColor;
                            color: $primaryColor;
                        }
                    }
                }
            }
        }
        .erp-form-modal-list{
            border: 1px solid #ccc;
            width:calc(100% - 265px);
            height: 100%;
            &.single{
                width: 100%;
            }
        }
    }
</style>
